package com.youlu.campus.web.community.service.impl;

import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.base.ContentTypeEnum;
import com.youlu.campus.base.base.InteractiveActionEnum;
import com.youlu.campus.base.community.ContentTopicBase;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.service.base.BaseService;
import com.youlu.campus.web.common.base.RequestContext;
import com.youlu.campus.web.qq.QQService;
import com.youlu.campus.web.community.dto.*;
import com.youlu.campus.web.community.entity.*;
import com.youlu.campus.web.community.service.CommContentService;
import com.youlu.campus.web.community.service.InteractiveService;
import com.youlu.campus.web.community.service.TopicCountService;
import com.youlu.campus.entity.UserPO;
import com.youlu.campus.web.common.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 社区内容接口实现类
 *
 * @author: YangJ
 * @date: 2020/11/26 14:49
 */
@Slf4j
@Service("commContentService")
public class CommContentServiceImpl extends BaseService implements CommContentService {

    @Autowired
    private TopicCountService topicCountService;

    @Autowired
    private InteractiveService interactiveService;

    @Autowired
    QQService qqService;

//    @Autowired
//    private MQService mqService;

    @Override
    public boolean create(CommContentRequest request) {

        //检查内容安全
        if (qqService.hasIllegal(request.getContent())) {
            throw new BusinessException("内容违规请重新发布!");
        }

        UserPO user = RequestContext.getCurUser();
        CommContent content = mapperFacade.map(request, CommContent.class);
        if (StringUtils.isNotBlank(request.getTopicType())) {
            //动态已关联话题
            content.setLinked(true);
        } else {
            content.setLinked(false);
        }
        content.setCreatorId(user.getId());
        content.setAvatarUrl(user.getAvatarUrl());
        content.setNickName(user.getNickName());
        content.setGender(user.getGender());
        content.setUniversityName(user.getUniversityName());
        content.setMajor(user.getMajor());

        mongoTemplate.insert(content);

        log.info("用户发布动态完成，信息:{}", JsonUtil.toJSON(content));

        if (content.getLinked() && content.getTopics() != null) {
            //记录用户参与的话题
            topicCountService.create(content.getTopics());
        }

        return true;
    }

    @Override
    public CommContentResponse query(String id) {
        log.info("查询动态信息开始，id:{}", id);
        CommContent content = find(id);

        CommContentResponse response = mapperFacade.map(content, CommContentResponse.class);
        log.info("查询动态信息结束");
        Query query = new Query().addCriteria(Criteria.where("infoId").is(id).and("creatorId").is(RequestContext.getCurUserId()));
        boolean exist = mongoTemplate.exists(query, ContentLike.class);
        response.setLiked(exist);

        Query query2 = new Query();
        query2.addCriteria(Criteria.where("userId").is(content.getCreatorId()));
        query2.addCriteria(Criteria.where("followerId").is(RequestContext.getCurUserId()));
        boolean exist2 = mongoTemplate.exists(query2, UserFollow.class);
        log.info(":>>> 当前用户:{},关注话题发布者:{} 是否关注:{}", content.getCreatorId(), RequestContext.getCurUserId(), exist2);
        response.setFollowed(exist2);

        //维护话题统计信息-热度数(+1)
        InteractiveMqRequest req = new InteractiveMqRequest();
        req.setType(ContentTypeEnum.DT.getCode());
        req.setAction(InteractiveActionEnum.HOT.getCode());
        req.setBid(id);
        req.setValue(1);
//        mqService.sendNormal(req, CampusMQDefinition.ROUTING_KEY_INTERACTIVE);

        return response;
    }

    @Override
    public boolean click(String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        Update update = new Update();
        update.inc("videoClickCount", 1);
        UpdateResult result = mongoTemplate.updateFirst(query, update, CommContent.class);
        if (result.getModifiedCount() > 0) {
            log.info("视频点击数，记录成功，动态id：{}", id);
        }
        return true;
    }

    private CommContent find(String id) {
        if (StringUtils.isBlank(id)) {
            throw new BusinessException("动态ID不能为空!");
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        CommContent content = mongoTemplate.findOne(query, CommContent.class);
        return content;
    }

    @Override
    public Page<CommContentResponse> contentList(ContentQueryRequest request) {

        Query query = new Query();
        query.addCriteria(Criteria.where("deleted").is(false));
        query.addCriteria(Criteria.where("displayed").is(true));
        if (StringUtils.isNotBlank(request.getUserGroupId())) {
            query.addCriteria(Criteria.where("userGroupId").is(request.getUserGroupId()));
        }
        if (StringUtils.isNotBlank(request.getTopicId())) {
            query.addCriteria(Criteria.where("topics.topicId").is(request.getTopicId()));
        }
        if (StringUtils.isNotBlank(request.getUserId())) {
            query.addCriteria(Criteria.where("creatorId").is(request.getUserId()));
        }
        long count = mongoTemplate.count(query, CommContent.class);

        PageRequest pageRequest = PageRequest.of(request.getPage() - 1, request.getPageSize());
        if (StringUtils.isNotBlank(request.getSortVal())
                && "new".equals(request.getSortVal())) {
//            query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        } else {
//            query.with(new Sort(Sort.Direction.DESC, "hotCount"));
//            query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        }
        List<CommContent> contents = mongoTemplate.find(query.with(pageRequest), CommContent.class);
        List<CommContentResponse> list = handleResponse(contents);
        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }

    private List<CommContentResponse> handleResponse(List<CommContent> contents) {
        List<CommContentResponse> list = contents.stream().map(content -> {
            CommContentResponse response = mapperFacade.map(content, CommContentResponse.class);
            if ("pk".equals(response.getTopicType())) {
                if (response.getTopics() != null && response.getTopics().size() > 0) {
                    ContentTopicResponse pk = handleTopicPk(response.getTopics().get(0).getTopicId());
                    response.setContentTopic(pk);
                }
            }
            response.setFollowed(interactiveService.queryIsFollow(response.getCreatorId()));
            response.setLiked(interactiveService.queryIsLike(response.getId(), ContentTypeEnum.DT.getCode()));
            return response;
        }).collect(Collectors.toList());

        return list;
    }

    private ContentTopicResponse handleTopicPk(String topicId) {
        ContentTopicResponse response = new ContentTopicResponse();

        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(topicId));
        TopicInfo topicInfo = mongoTemplate.findOne(query, TopicInfo.class);
        if (topicInfo == null) {
            return null;
        }
        response.setId(topicInfo.getId());
        response.setPkA(topicInfo.getPkA());
        response.setPkB(topicInfo.getPkB());
        TopicCountResponse percent = topicCountService.queryTopicCountPercent(topicId);
        response.setPkAPercent(percent.getPkAPercent());
        response.setPkBPercent(percent.getPkBPercent());
        TopicCount topicCount = topicCountService.queryUserVoted(topicId);
        if (topicCount != null) {
            response.setVoted(true);
            response.setVoteValue(topicCount.getSelectValue());
        }

        return response;
    }

    @Override
    public Page<CommContentResponse> contentFollowList(ContentQueryRequest request) {

        //查询关注人信息
        UserPO user = RequestContext.getCurUser();
        Query q = new Query();
        q.addCriteria(Criteria.where("followerId").is(user.getId()));
        PageRequest pr = PageRequest.of(0, 30);
//        q.with(new Sort(Sort.Direction.DESC, "status"));
//        q.with(new Sort(Sort.Direction.DESC, "createdTime"));
        List<UserFollow> follows = mongoTemplate.find(q.with(pr), UserFollow.class);
        if (follows == null || follows.size() <= 0) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pr, () -> 0);
        }
        Set<String> userIds = follows.stream().map(UserFollow::getUserId).collect(Collectors.toSet());
        log.info("关注人ids:{}", JsonUtil.toJSON(userIds));
        Query query = new Query();
        query.addCriteria(Criteria.where("deleted").is(false));
        query.addCriteria(Criteria.where("displayed").is(true));
        query.addCriteria(Criteria.where("creatorId").in(userIds));
        long count = mongoTemplate.count(query, CommContent.class);

        PageRequest pageRequest = PageRequest.of(request.getPage() - 1, request.getPageSize());
        if (StringUtils.isNotBlank(request.getSortVal())
                && "new".equals(request.getSortVal())) {
//            query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        } else {
//            query.with(new Sort(Sort.Direction.DESC, "hotCount"));
//            query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        }
        List<CommContent> contents = mongoTemplate.find(query.with(pageRequest), CommContent.class);
        List<CommContentResponse> list = handleResponse(contents);
        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }

    @Override
    public boolean delete(String id) {

        CommContent content = find(id);
        UserPO user = RequestContext.getCurUser();
        if (!content.getCreatorId().equals(user.getId())) {
            throw new BusinessException("非创建人不可删除!");
        }
        content.setDeleted(true);
        content.setDeleteTime(new Date());
        mongoTemplate.save(content);

        if(content.getLinked()&&content.getTopics().size() >0){
            for (ContentTopicBase topicBase :content.getTopics()) {
                //维护话题统计信息-动态数(-1)
                InteractiveMqRequest req = new InteractiveMqRequest();
                req.setType(ContentTypeEnum.HT.getCode());
                req.setAction(InteractiveActionEnum.CONTENT.getCode());
                req.setBid(topicBase.getTopicId());
                req.setValue(-1);
//                mqService.sendNormal(req, CampusMQDefinition.ROUTING_KEY_INTERACTIVE);


            }
        }
        if(content.getCommentCount() != null && content.getCommentCount() >0){
            //维护动态/话题统计信息-评论数(-N)
            InteractiveMqRequest req1 = new InteractiveMqRequest();
            req1.setType(ContentTypeEnum.DT.getCode());
            req1.setAction(InteractiveActionEnum.COMMENT.getCode());
            req1.setBid(content.getId());
            Long cc = content.getCommentCount();
            req1.setValue(-cc.intValue());
//            mqService.sendNormal(req1, CampusMQDefinition.ROUTING_KEY_INTERACTIVE);
        }

        return true;
    }


}
